package cn.sunxiansheng.mybatis.plus.page;

import lombok.*;

import java.io.Serializable;
import java.util.List;

import static java.util.Objects.requireNonNull;

/**
 * Description: 分页返回的实体
 *
 * @Author sun
 * @Create 2024-10-23 22:27:33
 * @Version 1.1
 */
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class PageResult<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    // 当前页码
    private Long pageNo;

    // 每页显示的记录数
    private Long pageSize;

    // 总记录条数
    private Long total;

    // 总页数
    private Long totalPages;

    // 当前页的记录列表
    private List<T> result;

    // 表示当前页是从分页查询结果的第几条记录开始，下标从1开始
    private Long start;

    // 表示当前页是从分页查询结果的第几条记录结束，下标从1开始
    private Long end;

    // 是否有下一页
    private boolean hasNextPage;

    // 是否有上一页
    private boolean hasPreviousPage;

    // 私有构造函数，使用Builder创建实例
    private PageResult(Builder<T> builder) {
        this.pageNo = builder.pageNo;
        this.pageSize = builder.pageSize;
        this.total = builder.total;
        this.result = builder.result;
        // 计算总页数
        calculateTotalPages();
        // 计算起始和结束位置
        calculateStartAndEnd();
        // 判断是否有上一页和下一页
        this.hasPreviousPage = this.pageNo > 1;
        this.hasNextPage = this.pageNo < this.totalPages;
    }

    // Builder 模式实现
    public static class Builder<T> {
        private Long pageNo;
        private Long pageSize;
        private Long total;
        private List<T> result;

        public Builder<T> pageNo(Long pageNo) {
            this.pageNo = requireNonNull(pageNo, "Page number cannot be null");
            return this;
        }

        public Builder<T> pageSize(Long pageSize) {
            this.pageSize = requireNonNull(pageSize, "Page size cannot be null");
            return this;
        }

        public Builder<T> total(Long total) {
            this.total = requireNonNull(total, "Total count cannot be null");
            return this;
        }

        public Builder<T> result(List<T> result) {
            this.result = requireNonNull(result, "Result list cannot be null");
            return this;
        }

        public PageResult<T> build() {
            // 校验参数
            if (pageNo < 1) {
                throw new IllegalArgumentException("Page number must be greater than zero.");
            }
            if (pageSize < 1) {
                throw new IllegalArgumentException("Page size must be greater than zero.");
            }
            return new PageResult<>(this);
        }
    }

    // 计算总页数
    private void calculateTotalPages() {
        if (this.pageSize > 0) {
            this.totalPages = (this.total / this.pageSize) + (this.total % this.pageSize == 0 ? 0 : 1);
        } else {
            // 如果 pageSize 小于 0，总页数为 0
            this.totalPages = 0L;
        }
    }

    // 计算起始和结束位置
    private void calculateStartAndEnd() {
        if (this.pageSize > 0) {
            this.start = (this.pageNo - 1) * this.pageSize + 1;
            this.end = Math.min(this.pageNo * this.pageSize, this.total);
        } else {
            // 如果 pageSize 小于 0，起始位置为 1，结束位置为总记录数
            this.start = 1L;
            this.end = this.total;
        }
    }
}
